package com.sziit.se.highconcurrency.order.application.controller;


import com.alibaba.fastjson.JSON;
import com.sziit.se.highconcurrency.common.annotation.IgnoreCheck;
import com.sziit.se.highconcurrency.common.result.DataResult;
import com.sziit.se.highconcurrency.common.result.Result;
import com.sziit.se.highconcurrency.common.result.ResultUtil;
import com.sziit.se.highconcurrency.order.application.entity.*;
import com.sziit.se.highconcurrency.order.application.feignclient.ProductFeign;
import com.sziit.se.highconcurrency.order.application.feignclient.UserFeign;
import com.sziit.se.highconcurrency.order.application.service.IOrderDetailService;
import com.sziit.se.highconcurrency.order.application.service.IOrderService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;



/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author dongchunkeng
 * @since 2022-11-09
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/order")
public class OrderDetailController {

    private final IOrderDetailService orderDetailService;

    private final IOrderService orderService;

    private final ProductFeign productFeign;

    private final UserFeign userFeign;




    @GetMapping
    @IgnoreCheck
    @RequestMapping("/order")
    public Result getOrderInfo(@RequestParam(value = "order_id") String orderId) throws InterruptedException {
        Order order = orderService.getOneData(orderId);
        List<OrderDetail> orderDetails = orderDetailService.getProductByOrderId(orderId);
        OnlyOrderInfo orderInfo = new OnlyOrderInfo();
        orderInfo.setOrderDetailList(orderDetails);
        orderInfo.setUser_id(order.getUserId());
        return ResultUtil.data(orderInfo);
    }


    @IgnoreCheck
    @PostMapping(value = "/order")
    @Transactional
    public Result createOrder(@RequestBody CreateOrderReq createOrderReq) throws Exception {

        String orderId = UUID.randomUUID().toString();
        List<ProductDetail> productDetails = createOrderReq.getProductDetailList();
        for (ProductDetail productDetail : productDetails) {
            String productId = productDetail.getProductId();
            DataResult productResult = productFeign.getProductById(productId);
            LinkedHashMap productHashMap = (LinkedHashMap) productResult.getData();
            Product product = JSON.parseObject(JSON.toJSONString(productHashMap), Product.class);

            if (null == product) {
                log.info("product is not on sail");
                throw new Exception("该商品不存在");
            }
            if (productDetail.getAmount() > product.getInventory()) {
                log.info("Inventory is lack");
                throw new Exception("库存不足，请减少购买数量");
            }
        }

        //根据订单中的每个商品购买数量，更新库存信息并将订单的详情保存在order_detail表中
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ProductDetail productDetail : productDetails) {
            String productId = productDetail.getProductId();
            DataResult productResult = productFeign.getProductById(productId);
            LinkedHashMap productHashMap = (LinkedHashMap) productResult.getData();
            Product product = JSON.parseObject(JSON.toJSONString(productHashMap), Product.class);
            product.setInventory(product.getInventory()-productDetail.getAmount());
            productFeign.updateProductById(product);
            orderDetailService.insertOrderDetail(orderId, productId, productDetail.getAmount());
            //组装orderDetails，作为返回值一部分返回
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orderId);
            orderDetail.setProductId(productId);
            orderDetail.setAmount(productDetail.getAmount());
            orderDetails.add(orderDetail);
        }
        //订单信息存入订单表中
        Boolean orderSuccess = orderService.insertOrder(orderId, createOrderReq.getUserId());
        OnlyOrderInfo orderInfo = new OnlyOrderInfo();
        orderInfo.setOrderDetailList(orderDetails);
        orderInfo.setUser_id(createOrderReq.getUserId());
        return ResultUtil.data(orderInfo);
    }

    @RequestMapping("/order/detail")
    public Result getOrderDetail(@RequestParam(value = "order_id") String orderId) throws InterruptedException {
        Order order = orderService.getOneData(orderId);
        List<OrderDetail> orderDetails = orderDetailService.getProductByOrderId(orderId);


        //从product微服务查询product信息，并组装成List<ProductDetail>
        List<ProductDetail> productDetailList = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetails) {
            String productId = orderDetail.getProductId();
            DataResult productResult = productFeign.getProductById(productId);
            LinkedHashMap productHashMap = (LinkedHashMap) productResult.getData();
            Product product = JSON.parseObject(JSON.toJSONString(productHashMap), Product.class);
            log.info("print product is" + product.getProductName());
            ProductDetail productDetail = new ProductDetail();
            productDetail.setProductName(product.getProductName());
            productDetail.setPrice(product.getPrice());
            productDetail.setProductId(product.getProductId());

            productDetailList.add(productDetail);
        }

        //从user微服务获取用户信息，远程调用
        DataResult userResult = userFeign.getUserById(order.getUserId());
        LinkedHashMap userHashMap = (LinkedHashMap) userResult.getData();
        User userInfo = JSON.parseObject(JSON.toJSONString(userHashMap), User.class);

        //将购买的产品信息和用户信息组装最后的响应体
        OrderDetailRsp orderDetailRsp = new OrderDetailRsp();
        orderDetailRsp.setProductDetailList(productDetailList);
        orderDetailRsp.setUserName(userInfo.getUserName());
        orderDetailRsp.setPhone(userInfo.getPhone());
        orderDetailRsp.setOrderId(order.getOrderId());
        orderDetailRsp.setUserId(userInfo.getUserId());

        return ResultUtil.data(orderDetailRsp);
    }
}
